<template>

    <div class="item-group-container">
        <!-- 顶部操作区域 -->
        <div class="top-section">
            <transition name="search-slide">
                <div class="search-area" v-show="showSearchArea">
                    <div class="search-status" v-if="hasSearchConditions">
                        <el-tag size="small" type="info">
                            当前搜索条件: {{ getSearchConditionsText() }}
                        </el-tag>
                        <el-tag size="small" type="success" style="margin-left: 10px;">
                            找到 {{ total }} 条结果
                        </el-tag>
                    </div>
                    <!-- <el-input v-model="searchForm.ProcessCode" placeholder="请输入编码" class="search-input" clearable
                        @keyup.enter="handleSearch" /> 175-92A 40-->
                    <el-input v-model="searchForm.RoutingName" placeholder="请输入名称" class="search-input" clearable
                        @keyup.enter="handleSearch" />

                    <el-select v-model="searchForm.RoutStatus" placeholder="请选择群组类型" class="search-input" clearable
                        @change="handleSearch">

                        <el-option v-for="item in groupTypes" :key="item.id" :label="item.groupTypeName"
                            :value="item.id" />
                    </el-select>
                    <el-button type="primary" @click="handleSearch" class="search-btn">
                        <el-icon>
                            <Search />
                        </el-icon>
                        搜索
                    </el-button>
                    <el-button @click="clearSearch" class="clear-btn">
                        <el-icon>
                            <Close />
                        </el-icon>
                        清空
                    </el-button>
                    <el-dropdown @command="loadSearchHistory" v-if="searchHistory.length > 0">
                        <el-button class="history-btn">
                            <el-icon>
                                <Clock />
                            </el-icon>
                            历史
                            <el-icon class="el-icon--right">
                                <ArrowDown />
                            </el-icon>
                        </el-button>
                        <template #dropdown>
                            <el-dropdown-menu>
                                <el-dropdown-item v-for="(item, index) in searchHistory" :key="index" :command="item">
                                    {{ getSearchHistoryText(item) }}
                                </el-dropdown-item>
                            </el-dropdown-menu>
                        </template>
                    </el-dropdown>
                </div>
            </transition>
            <div class="action-buttons">
                <el-button type="primary" @click="handleAdd" class="action-btn">
                    <el-icon>
                        <Plus />
                    </el-icon>
                    新增
                </el-button>
                <el-button type="primary" @click="handleExport" class="action-btn">
                    <el-icon>
                        <Download />
                    </el-icon>
                    导出
                </el-button>
                <el-button @click="handleBatchDelete" class="action-btn delete-btn">
                    <el-icon>
                        <Delete />
                    </el-icon>
                    删除
                </el-button>
            </div>
            <div class="utility-icons">
                <el-tooltip :content="showSearchArea ? '隐藏搜索' : '显示搜索'" placement="top">
                    <el-icon class="icon-btn" @click="toggleSearchArea" :class="{ 'active': showSearchArea }">
                        <Search />
                    </el-icon>
                </el-tooltip>
                <el-tooltip content="刷新" placement="top">
                    <el-icon class="icon-btn" @click="refreshData">
                        <Refresh />
                    </el-icon>
                </el-tooltip>
                <el-tooltip content="全屏" placement="top">
                    <el-icon class="icon-btn" @click="toggleFullscreen">
                        <Expand />
                    </el-icon>
                </el-tooltip>
                <el-tooltip content="设置" placement="top">
                    <el-icon class="icon-btn">
                        <Setting />
                    </el-icon>
                </el-tooltip>
                <el-tooltip content="关闭" placement="top">
                    <el-icon class="icon-btn">
                        <Close />
                    </el-icon>
                </el-tooltip>
            </div>
        </div>

        <!-- 数据表格 -->
        <div class="table-section">
            <el-table :data="tableData" v-loading="loading" @selection-change="handleSelectionChange" class="data-table"
                border stripe>
                <el-table-column type="selection" width="55" />
                <el-table-column prop="index" label="序号" width="80" align="center">
                    <template #default="scope">
                        {{ scope.$index + 1 }}
                    </template>
                </el-table-column>
                <el-table-column prop="routingName" label="名称" width="150" align="center">
                    <template #header>
                        <span>名称</span>
                        <el-icon class="search-icon">
                            <Search />
                        </el-icon>
                    </template>
                </el-table-column>
                <el-table-column prop="routingImg" label="预览图" width="200" align="center">
                    <template #header>
                        <span>预览图</span>
                        <el-icon class="search-icon">
                            <Search />
                        </el-icon>
                    </template>
                    <template #default="scope">
                        <el-image style="width: 100px; height: 100px" :src="scope.row.routingImg" fit="contain"
                            :preview-src-list="[scope.row.routingImg]" ide-on-click-modal preview-teleported="true" />
                    </template>
                    <!--  <el-image style="width: 100px; height: 100px" src="scope.row.routingImg" fit="contain" /> -->
                </el-table-column>
                <el-table-column prop="routingTypeId" label="类型" width="150" align="center">
                    <template #header>
                        <span>类型</span>
                        <el-icon class="search-icon">
                            <Search />
                        </el-icon>
                    </template>
                    <template #default="scope">
                        <el-tag :type="getTagType(scope.row.routingTypeId)" size="small">
                            {{ scope.row.routingTypeId }}
                        </el-tag>
                    </template>
                </el-table-column>
                <el-table-column prop="routStatus" label="状态" width="180" align="center">
                    <template #header>
                        <span>状态</span>
                        <el-icon class="search-icon">
                            <Search />
                        </el-icon>
                    </template>
                    <template #default="scope">
                        <el-tag :type="getTagType(scope.row.routStatus)" size="small">
                            {{ scope.row.routStatus == 1 ? "已发布" : "未发布" }}
                        </el-tag>
                    </template>
                </el-table-column>
                <el-table-column prop="routingMsg" label="描述" min-width="150" align="center" />
                <el-table-column prop="addProp" label="创建人" width="120" align="center" />
                <el-table-column prop="addTime" label="创建时间" width="160" align="center">
                    <template #header>
                        <span>创建时间</span>
                        <el-icon class="search-icon">
                            <Search />
                        </el-icon>
                        <el-icon class="sort-icon">
                            <Sort />
                        </el-icon>
                    </template>
                    <template #default="scope">
                        {{ moment(scope.row.addTime).format("YYYY-MM-DD HH:mm:ss") }}
                    </template>
                </el-table-column>
                <el-table-column prop="updTime" label="更新时间" width="160" align="center">
                    <template #default="scope">
                        {{ scope.row.updTime == null ? "" : moment(scope.row.updTime).format("YYYY-MM-DD HH:mm:ss") }}
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="300" align="center" fixed="right">
                    <template #default="scope">
                        <el-button type="text" plain @click="Open(scope.row)">
                            绘制流程
                        </el-button>
                        <el-button type="text" @click="handleEdit(scope.row)" class="action-link">
                            编辑
                        </el-button>
                        <el-button type="text" @click="handleDelete(scope.row)" class="action-link delete-link">
                            删除
                        </el-button>
                        <el-dropdown>
                            <span class="el-dropdown-link">
                                其他
                                <el-icon class="el-icon--right">
                                    <arrow-down />
                                </el-icon>
                            </span>
                            <template #dropdown>
                                <el-dropdown-menu>
                                    <el-dropdown-item :disabled="scope.row.routStatus == 1 ? true : false">
                                        <el-button type="text" class="action-link"
                                            :disabled="scope.row.routStatus == 1 ? true : false"
                                            @click="updStatus(scope.row, 1)">
                                            发布
                                        </el-button>
                                    </el-dropdown-item>
                                    <el-dropdown-item :disabled="scope.row.routStatus == 0 ? true : false">
                                        <el-button class="action-link delete-link" type='text'
                                            :disabled="scope.row.routStatus == 0 ? true : false"
                                            @click="updStatus(scope.row, 0)">
                                            取消发布
                                        </el-button>
                                    </el-dropdown-item>
                                </el-dropdown-menu>
                            </template>
                        </el-dropdown>
                    </template>
                </el-table-column>
            </el-table>
        </div>

        <!-- 分页区域 -->
        <div class="pagination-section">
            <div class="data-summary">
                共{{ total }}条数据
            </div>
            <div class="pagination-controls">
                <el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize"
                    :page-sizes="[10, 20, 50, 100]" :total="total" layout="total, sizes, prev, pager, next, jumper"
                    @size-change="handleSizeChange" @current-change="handleCurrentChange" />
            </div>
        </div>

        <!-- 新增/编辑对话框 -->
        <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px" @close="resetForm">
            <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
                <!-- <el-form-item label="编码" prop="processCode">
                    <el-input v-model="form.processCode" placeholder="请输入群组编码" />
                </el-form-item> -->
                <el-form-item label="名称" prop="routingName">
                    <el-input v-model="form.routingName" placeholder="请输入工艺路线名称" />
                </el-form-item>
                <el-form-item label="类型" prop="routingTypeId">
                    <el-select v-model="form.routingTypeId" placeholder="请选择群组类型" style="width: 100%">
                        <el-option label="生产" value="生产" />
                        <el-option label="维修" value="维修" />
                        <el-option label="锡膏" value="锡膏" />
                    </el-select>
                </el-form-item>
                <!-- <el-form-item label="状态" prop="routStatus">
                    <el-radio-group v-model="form.routStatus">
                        <el-radio value="数量" size="large">数量</el-radio>
                        <el-radio value="状态" size="large">状态</el-radio>
                    </el-radio-group>

                </el-form-item> -->
                <el-form-item label="描述" prop="routingMsg">
                    <el-input v-model="form.routingMsg" type="textarea" :rows="3" placeholder="请输入群组描述" />
                </el-form-item>
            </el-form>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="dialogVisible = false">取消</el-button>
                    <el-button type="primary" @click="submitForm">确定</el-button>
                </span>
            </template>
        </el-dialog>
        <el-dialog v-model="dialogTableVisible" title="设置流程" width="1300" align-center draggable overflow>
            <div class="flow-container">
                <VueFlow :nodes="nodes" :edges="edges" :default-viewport="{ zoom: 1 }" :min-zoom="0.2" :max-zoom="4"
                    @node-click="onNodeClick" @edge-click="onEdgeClick" @drop="onDrop" @dragover="onDragOver"
                    :node-types="nodeTypes" :default-edge-options="defaultEdgeOptions" :connect-on-click="true"
                    class="vue-flow-container">
                    <Background pattern-color="#7300ff" :gap="16" />
                    <MiniMap />
                </VueFlow>
                <div class="top-container">
                    <Controls class="controls" />
                    <div class="save-btn">
                        <ElButton type="primary" class="mr-2" @click="saveFlow">保存</ElButton>
                    </div>
                </div>
                <div class="left-panel">
                    <div class="drag-items">
                        <ElRow :gutter="10">
                            <ElCol :span="12">
                                <div class="drag-item start-node" draggable="true"
                                    @dragstart="onDragStart($event, '开始')" @dragend="onDragEnd">
                                    <span>开始</span>
                                </div>
                            </ElCol>
                            <ElCol :span="12">
                                <div class="drag-item end-node" draggable="true" @dragstart="onDragStart($event, '结束')"
                                    @dragend="onDragEnd">
                                    <span>结束</span>
                                </div>
                            </ElCol>
                        </ElRow>
                        <ElScrollbar height="75%">
                            <div class="drag-item custom-node" draggable="true"
                                @dragstart="onDragStart($event, item.name)" @dragend="onDragEnd"
                                v-for="(item, index) in pointsList" :key="index">
                                <span>{{ item.name }}</span>
                            </div>
                        </ElScrollbar>
                    </div>
                </div>
                <div class="right-panel" v-if="updateState">
                    <div class="panel-header">
                        <span>{{
                            updateState === "edge" ? "连接线规则配置" : "点位规则配置"
                        }}</span>
                        <ElButton circle class="close-btn" @click="updateState = ''">×</ElButton>
                    </div>
                    <div class="panel-content" v-if="updateState === 'edge'">
                        <ElInput v-model="selectedEdgeData.label" placeholder="线名称" clearable />
                        <ElSelect v-model="selectedEdgeData.type" placeholder="线类型">
                            <ElOption label="折线" value="smoothstep" />
                            <ElOption label="曲线" value="default" />
                            <ElOption label="直线" value="straight" />
                        </ElSelect>
                        <ElSelect v-model="selectedEdgeData.animated" placeholder="线动画">
                            <ElOption label="开启" :value="true" />
                            <ElOption label="关闭" :value="false" />
                        </ElSelect>
                        <ElButton type="primary" @click="updateEdge">修改</ElButton>
                        <ElButton type="danger" @click="removeEdge">删除</ElButton>
                    </div>
                    <div class="panel-content" v-else>
                        <ElInput v-model="selectedNodeData.data.label" placeholder="点位名称" clearable />
                        <ElButton type="primary" @click="updateNodeLabel">修改</ElButton>
                        <ElButton type="danger" @click="removeNode">删除</ElButton>
                    </div>
                </div>
            </div>
        </el-dialog>
    </div>


</template>
<script lang="ts" setup>
//#region 导入 和生命周期
import { ref, markRaw, reactive, computed, onMounted, onUnmounted } from "vue";
import {
    VueFlow,
    useVueFlow,
    MarkerType,
    type Node,
    type Edge,
    type Connection
} from "@vue-flow/core";
import { Background } from '@vue-flow/background'
import { Controls } from "@vue-flow/controls";
import { MiniMap } from "@vue-flow/minimap";
import '@vue-flow/controls/dist/style.css'
import "@vue-flow/core/dist/style.css";
import '@vue-flow/minimap/dist/style.css'
import "@vue-flow/core/dist/theme-default.css";
import CustomNode from "./CustomNode.vue";
import {
    ElMessageBox,
    ElNotification,
    ElButton,
    ElRow,
    ElCol,
    ElScrollbar,
    ElInput,
    ElSelect,
    ElOption,
    ElMessage
} from "element-plus";
import {
    Plus,
    Download,
    Delete,
    Grid,
    Search,
    Refresh,
    Expand,
    Setting,
    Close,
    Sort,
    Clock,
    ArrowDown
} from '@element-plus/icons-vue'
import Maxios from "@/Http/MesHelp";
import moment from "moment";
import html2canvas from 'html2canvas';
const { vueFlowRef } = useVueFlow();
// ==================== 生命周期钩子 ====================
// 组件挂载时初始化数据
onMounted(() => {
    getItemGroups() // 获取物料群组列表数据
    GetPoints()
    // 添加键盘事件监听器
    document.addEventListener('keydown', handleKeydown)
})

// 组件卸载时清理事件监听器
onUnmounted(() => {
    document.removeEventListener('keydown', handleKeydown) // 移除键盘事件监听器
})
//#endregion

//#region vue-flow
// 使用VueFlow组合式API
const {
    onInit,
    onNodeDragStop,
    onConnect,
    addEdges,
    getNodes,
    getEdges,
    setEdges,
    setNodes,
    screenToFlowCoordinate,
    onNodesInitialized,
    updateNode, // 从VueFlow导入的updateNode函数
    addNodes,
    findNode
} = useVueFlow();
var rows = ref({
    "routingName": "",
    "routingImg": "",
    "routingImgJSON": "",
    "routingTypeId": "",
    "routStatus": "",
    "routingMsg": "",
    "id": "",
    "addProp": "印章",
    "addTime": "",
    "updProp": "印章",
    "updTime": "",
    "isDel": false
})

const dialogTableVisible = ref(false)
//打开vueflow及内部数据显示
const Open = (row: any) => {
    rows.value = row
    //判断json是否有值,有则赋值,无,则默认
    nodes.value = [{
        id: "5",
        type: "input",
        data: { label: "开始" },
        position: { x: 235, y: 100 },
        class: "round-start"
    },
    {
        id: "7",
        type: "output",
        data: { label: "结束" },
        position: { x: 235, y: 300 },
        class: "round-stop"
    }]
    edges.value = []
    if ( row.routingImgJSON != ""&& row.routingImgJSON != undefined&& row.routingImgJSON != "null"&& row.routingImgJSON != "undefined" && row.routingImgJSON != " "&& row.routingImgJSON.length > 10) {
        console.log("wtf?");
        
        var msg = JSON.parse(row.routingImgJSON)
        console.log(msg);
        nodes.value = msg.nodes
        edges.value = msg.edges
    }
    dialogTableVisible.value = true
}

//获取节点赋值
const GetPoints = async () => {
    const response = await Maxios.get(`${API_BASE_URL}/Process/GetProcess`, {
        params: {
            ProcessCode: null,
            ProcessName: null,
            StepTypeId: null,
            PageIndex: 1, // 当前页码
            PageSize: 99 // 每页显示数量
        }
    })

    if (response.data.code === 200) {
        // 假设接口返回的每个项中，点位名称字段为ProcessName，转换为name属性
        pointsList.value = response.data.data.list.map((item: any) => ({
            name: item.processName || '未命名点位' // 若字段不同，替换为实际字段名
        }));
        console.log("处理后的点位列表：", pointsList.value);

    }
}
// 默认边选项
const defaultEdgeOptions = ref({
    type: "smoothstep", // 默认边类型
    animated: true, // 是否启用动画
    markerEnd: {
        type: MarkerType.ArrowClosed, // 默认箭头样式
        color: "black"
    }
});

// 节点数据
const nodes = ref<Node[]>([
    {
        id: "5",
        type: "input",
        data: { label: "开始" },
        position: { x: 235, y: 100 },
        class: "round-start"
    },
    {
        id: "6",
        type: "custom", // 使用自定义类型
        data: { label: "工位：流程1" },
        position: { x: 200, y: 200 },
        class: "light"
    },
    {
        id: "7",
        type: "output",
        data: { label: "结束" },
        position: { x: 235, y: 300 },
        class: "round-stop"
    }
]);

// 节点类型
const nodeTypes = ref<any>({
    custom: markRaw(CustomNode) // 注册自定义节点类型
});

// 边数据
const edges = ref<Edge[]>([
    {
        id: "e4-5",
        type: "straight",
        source: "5",
        target: "6",
        sourceHandle: "top-6",
        label: "测试1",
        markerEnd: {
            type: MarkerType.ArrowClosed, // 使用闭合箭头
            color: "black"
        }
    },
    {
        id: "e4-6",
        type: "straight",
        source: "6",
        target: "7",
        sourceHandle: "bottom-6",
        label: "测试2",
        markerEnd: {
            type: MarkerType.ArrowClosed, // 使用闭合箭头
            color: "black"
        }
    }
]);

// 初始化
onInit(vueFlowInstance => {
    vueFlowInstance.fitView();
});
function doScreenshot() {
    if (!vueFlowRef.value) {
        console.warn('VueFlow element not found');
        return;
    }
    console.log(vueFlowRef.value);
    //   capture(vueFlowRef.value, { shouldDownload: true });
}
// 节点拖拽停止事件
onNodeDragStop(({ event, node }) => {
    console.log("Node Drag Stop", { event, node });
});

// 连接事件
onConnect((connection: Connection) => {
    addEdges({ ...connection, type: defaultEdgeOptions.value.type });
});

// 点位列表---------------------------------------------------------------------------
const pointsList = ref([{ name: "测试1" }, { name: "测试2" }]);
// 更新状态（节点或边）
const updateState = ref<"node" | "edge" | "">("");

// 选中的边数据
const selectedEdgeData = reactive<{
    id: string;
    type?: string;
    label?: string;
    animated?: boolean;
}>({ id: "", type: undefined, label: undefined, animated: undefined });

// 边点击事件
const onEdgeClick = ({ edge }: { edge: Edge }) => {
    Object.assign(selectedEdgeData, edge); // 更新选中的边数据
    updateState.value = "edge";
    console.log("选中的边：", selectedEdgeData);
};

// 更新边
function updateEdge() {
    const allEdges = getEdges.value;
    setEdges(
        allEdges.map(e =>
            e.id === selectedEdgeData.id
                ? { ...e, type: selectedEdgeData.type, label: selectedEdgeData.label, animated: selectedEdgeData.animated }
                : e
        )
    );
}

// 删除边
function removeEdge() {
    ElMessageBox.confirm("是否要删除该连线？", "删除连线", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
    }).then(() => {
        const allEdges = getEdges.value;
        setEdges(allEdges.filter(e => e.id !== selectedEdgeData.id));
        ElNotification({
            type: "success",
            message: "连线删除成功"
        });
        updateState.value = "";
        Object.assign(selectedEdgeData, { id: "", type: undefined, label: undefined, animated: undefined });
    });
}

// 选中的节点数据
const selectedNodeData = reactive<{
    id: string;
    data: { label: string };
    type: string;
    position: { x: number; y: number };
    class: string;
}>({
    id: "",
    data: { label: "" },
    type: "",
    position: { x: 0, y: 0 },
    class: ""
});

// 节点点击事件
const onNodeClick = ({ node }: { node: Node }) => {
    Object.assign(selectedNodeData, node); // 更新选中的节点数据
    updateState.value = "node";
    console.log("选中的节点：", node);
};

// 更新节点标签（重命名以避免冲突）
function updateNodeLabel() {
    updateNode(selectedNodeData.id, {
        data: {
            label: selectedNodeData.data.label
        }
    });
}

// 删除节点
function removeNode() {
    ElMessageBox.confirm("是否要删除该点位？", "删除点位", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
    }).then(() => {
        const allNodes = getNodes.value;
        setNodes(allNodes.filter(e => e.id !== selectedNodeData.id));
        const allEdges = getEdges.value;
        setEdges(
            allEdges.filter(
                e =>
                    e.source !== selectedNodeData.id &&
                    e.target !== selectedNodeData.id
            )
        );
        ElNotification({
            type: "success",
            message: "点位删除成功"
        });
        updateState.value = "";
        Object.assign(selectedNodeData, {
            id: "",
            data: { label: "" },
            type: "",
            position: { x: 0, y: 0 },
            class: ""
        });
    });
}

// 拖拽项
const dragItem = ref<Node | null>(null);

// 拖拽开始事件
function onDragStart(event: DragEvent, state: string) {
    if (!event.dataTransfer) return;

    event.dataTransfer.setData("application/vueflow", "true");
    event.dataTransfer.effectAllowed = "move";

    dragItem.value = {
        id: `node-${Date.now()}`,
        data: {
            label:
                state === "开始" ? "开始" : state === "结束" ? "结束" : state
        },
        type: state === "开始" ? "input" : state === "结束" ? "output" : "custom",
        position: { x: 0, y: 0 },
        class:
            state === "开始"
                ? "round-start"
                : state === "结束"
                    ? "round-stop"
                    : "light"
    };
}

// 拖拽结束事件
function onDragEnd() {
    dragItem.value = null;
}

// 拖拽经过事件
function onDragOver(event: DragEvent) {
    event.preventDefault();
    if (!event.dataTransfer) return;

    event.dataTransfer.dropEffect = "move";
}

// 放置事件
function onDrop(event: DragEvent) {
    event.preventDefault();

    if (!dragItem.value) return;

    const position = screenToFlowCoordinate({
        x: event.clientX,
        y: event.clientY
    });

    const newNode = {
        ...dragItem.value,
        position
    };

    const { off } = onNodesInitialized(() => {
        const node = findNode(newNode.id);
        if (node) {
            updateNode(newNode.id, {
                position: {
                    x: node.position.x - node.dimensions.width / 2,
                    y: node.position.y - node.dimensions.height / 2
                }
            });
        }
        off();
    });

    addNodes(newNode);
    dragItem.value = null;
}

// 保存流程
// const saveFlow = async () => {
//     // console.log("All数据:",getNodes)
//     // console.log("保存数据nodes：", getNodes.value);
//     // console.log("保存数据edges", getEdges.value);
//     var node = JSON.stringify(getNodes.value)
//     // console.log('{"node":'+node+'}');
//     var edges = JSON.stringify(getEdges.value)
//     // console.log('{"edges":'+edges+'}');
//     var mix = '{"nodes":' + JSON.stringify(getNodes.value) + ',' + '"edges":' + JSON.stringify(getEdges.value) + '}'
//     console.log(mix);
//     // 保存流程（先上传截图获取路径，再更新数据）
const saveFlow = async () => {
    try {
        // 1. 收集基础数据（流程图数据、流程ID）
        const flowData = {
            nodes: getNodes.value,
            edges: getEdges.value
        };
        const flowDataJson = JSON.stringify(flowData);

        if (!rows.value.id) {
            ElMessage.error('未找到流程ID，无法保存');
            return;
        }

        // 2. 生成流程图截图
        const vueFlowContainer = document.querySelector('.vue-flow-container');
        if (!(vueFlowContainer instanceof HTMLElement)) {
            ElMessage.error('未找到流程图容器，无法生成截图');
            return;
        }

        const canvas = await html2canvas(vueFlowContainer, {
            useCORS: true,
            scale: 2, // 提高清晰度
            logging: false,
            backgroundColor: '#ffffff' // 确保背景为白色
        });

        // 3. 第一步：上传截图到后端，获取图片保存路径
        canvas.toBlob(async (blob) => {
            if (!blob) {
                ElMessage.error('截图生成失败');
                return;
            }

            // 3.1 构造截图上传的FormData
            const screenshotForm = new FormData();
            screenshotForm.append('file', blob, `flow-${Date.now()}.png`);

            // 3.2 调用截图上传接口（假设接口为：/api/Process/UploadScreenshot）
            const uploadRes = await Maxios.post('/api/Images/UploadImagesAsync', screenshotForm, {
                /*headers: { 'Content-Type': 'multipart/form-data' }*/
            });

            if (uploadRes.data.code !== 200 || !uploadRes.data.data?.imageUrl) {
                ElMessage.error('截图上传失败：' + (uploadRes.data.message || '未返回图片路径'));
                return;
            }

            // 3.3 从返回结果中获取图片路径
            console.log(uploadRes);

            const imageUrl = uploadRes.data.data.imageUrl;
            ElMessage.success('截图上传成功');

            // 4. 第二步：用图片路径 + JSON数据更新流程记录
            // 4.1 构造更新数据（包含图片路径和流程图JSON）

            rows.value.routingImg = imageUrl
            rows.value.routingImgJSON = flowDataJson
            // 4.2 调用数据更新接口（假设接口为：/api/Process/UpdateRoutingData）
            const updateRes = await Maxios.put('/api/Process/RoutingUpdate', rows.value);

            if (updateRes.data.code === 200) {
                ElMessage.success('流程图数据保存成功');
                dialogTableVisible.value = false; // 关闭对话框
                getItemGroups(); // 刷新列表
            } else {
                ElMessage.error('数据更新失败：' + (updateRes.data.message || '未知错误'));
            }
        }, 'image/png');
    } catch (error) {
        console.error('保存流程失败:', error);
        ElMessage.error('保存过程发生错误');
    }
};
// };
//#endregion

//#region 增删改查基本操作盘

// 接口定义
interface ItemGroup {
    id: number
    addProp: string
    addTime: string
    updProp?: string
    updTime?: string
    isDel: boolean
    /*--------下部为替换部分---------*/
    routingName: string
    routingImg: string
    routingImgJSON: string
    routingTypeId: string
    routStatus: string
    routingMsg: string

}

interface GroupType {
    id: string
    groupTypeName: string
}

interface ProcessRoute {
    Id: number
    RouteName: string
}

// ==================== 响应式数据定义 ====================
const loading = ref(false) // 表格加载状态
const tableData = ref<ItemGroup[]>([]) // 表格数据
const selectedRows = ref<ItemGroup[]>([]) // 选中的行数据
const currentPage = ref(1) // 当前页码
const pageSize = ref(10) // 每页显示数量
const total = ref(0) // 总数据量
const dialogVisible = ref(false) // 对话框显示状态
const dialogTitle = ref('新增') // 对话框标题
const isEdit = ref(false) // 是否为编辑模式
const groupTypes = ref<GroupType[]>([{ id: '0', groupTypeName: '未发布' }, { id: '1', groupTypeName: '已发布' }]) // 群组类型数据
const processRoutes = ref<ProcessRoute[]>([]) // 工艺路线数据
const showSearchArea = ref(true) // 搜索区域显示状态
const searchHistory = ref<Array<{ ItemName: string, ItemTypeId: string }>>([]) // 搜索历史记录

// ==================== 表单数据定义 ====================
// 搜索表单数据
const searchForm = reactive({
    // ProcessCode: '', // 群组编码搜索条件
    RoutingName: '', // 群组名称搜索条件
    RoutStatus: '' // 群组类型搜索条件
})

// 新增/编辑表单数据
const formRef = ref() // 表单引用
const form = reactive({
    id: 0, // 物料群组ID
    routingName: '', // 工艺路线名称
    routingImg: '', // 工艺路线图
    routingImgJSON: '', // 工艺路线流程
    routingTypeId: "", // 工艺路线类型
    routStatus: "", // 工艺路线状态
    routingMsg: "",//工艺路线描述
    addProp: localStorage.getItem("userNickname") || '', // 创建人
    addTime:'', // 创建时间
})

// 新建表单验证规则
const rules = {
    routingName: [
        { required: true, message: '请输入工艺流程名称', trigger: 'blur' } // 群组编码必填
    ],
    routingTypeId: [
        { required: true, message: '请输入工艺流程分类', trigger: 'blur' } // 群组名称必填
    ],
    routingMsg: [
        { required: true, message: '请输入工艺路线描述', trigger: 'blur' } // 群组类型必选
    ]
}

// ==================== API接口方法 ====================
// API基础URL配置
const API_BASE_URL = '/api'  // 后端控制器路由为 api/[controller]/[action]

// 获取物料群组列表数据
const getItemGroups = async () => {
    loading.value = true
    try {
        // 调用后端API获取物料群组数据（包含分页参数）
        const response = await Maxios.get(`${API_BASE_URL}/Process/GetRouting`, {
            params: {
                // ProcessCode: searchForm.ProcessCode || null,
                RoutingName: searchForm.RoutingName || null,
                RoutStatus: searchForm.RoutStatus || null,
                PageIndex: currentPage.value, // 当前页码
                PageSize: pageSize.value // 每页显示数量
            }
        })

        if (response.data.code === 200) {
            const result = response.data.data // 获取分页结果对象

            console.log('API返回数据:', result)

            // 直接使用后端返回的数据（已包含类型名称和工艺路线名称）
            tableData.value = result.list || []
            total.value = result.count || 0
            currentPage.value = result.pageIndex || 1
            pageSize.value = result.pageSize || 10

            console.log('数据设置完成:', {
                total: total.value,
                tableDataLength: tableData.value.length,
                tableData: tableData.value
            })
        } else {
            ElMessage.error(response.data.message || '获取数据失败')
        }
    }
    catch (error) {
        console.error('获取物料群组失败:', error)
        console.log('API调用详情:', {
            url: `${API_BASE_URL}/ItemGroup/ItemGroupQuery`,
            fullUrl: `http://localhost:5293${API_BASE_URL}/ItemGroup/ItemGroupQuery`,
            params: {
                // ProcessCode: searchForm.ProcessCode || null,
                RoutingName: searchForm.RoutingName || null,
                ItemMsg: null,
                RoutStatus: searchForm.RoutStatus,
                PageIndex: currentPage.value,
                PageSize: pageSize.value
            }
        })
        // 如果API调用失败，使用模拟数据
        console.log('使用模拟数据...')
        const mockData: ItemGroup[] = [
            {
                id: 1,
                routingName: "string",
                routingImg: "string",
                routingImgJSON: "string",
                routingTypeId: "string",
                routStatus: "string",
                routingMsg: "string",
                addProp: '(test)管理员',
                addTime: '2024-01-15 10:30:00',
                updTime: '',
                isDel: true
            },
            {
                id: 2,
                routingName: "string",
                routingImg: "string",
                routingImgJSON: "string",
                routingTypeId: "string",
                routStatus: "string",
                routingMsg: "string",
                addProp: '(test)管理员',
                addTime: '2024-01-16 14:20:00',
                updTime: '',
                isDel: true
            },
            {
                id: 3,
                routingName: "string",
                routingImg: "string",
                routingImgJSON: "string",
                routingTypeId: "string",
                routStatus: "string",
                routingMsg: "string",
                addProp: '(test)管理员',
                addTime: '2024-01-17 09:15:00',
                updTime: '',
                isDel: true
            }
        ]

        // 过滤数据
        let filteredData = mockData
        // if (searchForm.ProcessCode) {
        //     filteredData = filteredData.filter(item =>
        //         item.processCode.toLowerCase().includes(searchForm.ProcessCode.toLowerCase())
        //     )
        // }
        if (searchForm.RoutingName) {
            filteredData = filteredData.filter(item =>
                item.routingName.toLowerCase().includes(searchForm.RoutingName.toLowerCase())
            )
        }
        if (searchForm.RoutStatus) {
            filteredData = filteredData.filter(item =>
                item.routStatus.toLowerCase().includes(searchForm.RoutStatus.toLowerCase()))
        }

        total.value = filteredData.length
        const start = (currentPage.value - 1) * pageSize.value
        const end = start + pageSize.value
        tableData.value = filteredData.slice(start, end)
        console.log('模拟数据分页:', {
            total: total.value,
            currentPage: currentPage.value,
            pageSize: pageSize.value,
            start,
            end,
            dataLength: tableData.value.length
        })
        console.log('模拟数据设置完成:', {
            total: total.value,
            tableDataLength: tableData.value.length,
            tableData: tableData.value
        })
    } finally {
        loading.value = false
    }
}

// ==================== 业务逻辑方法 ====================
// 根据类型ID获取对应的标签样式类型
const getTagType = (typeId: string) => {
    const typeMap: { [key: string]: string } = {
        0: 'danger',
        1: 'success',    // 原材料 - 红色标签
        锡膏: 'warning',   // 成品 - 橙色标签
        生产: 'primary',      // 上工件 - 蓝色标签
        维修: 'success'    // 半成品 - 绿色标签
    }
    return typeMap[typeId] || 'info' // 默认返回蓝色标签
}

// 新增物料群组
const handleAdd = () => {
    isEdit.value = false // 设置为新增模式
    dialogTitle.value = '新增'
    dialogVisible.value = true // 显示对话框
    resetForm() // 重置表单数据
}

// 编辑物料群组
const handleEdit = (row: ItemGroup) => {
    isEdit.value = true // 设置为编辑模式
    dialogTitle.value = '编辑'
    dialogVisible.value = true // 显示对话框
    console.log(row);

    Object.assign(form, row) // 将行数据填充到表单中
    console.log(form);
}

// 删除单个物料群组
const handleDelete = async (row: ItemGroup) => {
    try {
        // 确认删除操作
        await ElMessageBox.confirm('确定要删除这个物料群组吗？', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
        })
        console.log(row);

        // 调用删除API
        const response = await Maxios.delete(`${API_BASE_URL}/Process/RoutingDelete`, { data: { row, Id: row.id, AddProp: row.addProp, RoutingMsg: row.routingMsg, RoutingName: row.routingName, RoutingTypeId: row.routingTypeId } })

        if (response.data.code === 200) {
            ElMessage.success('删除成功')
            getItemGroups() // 刷新数据
        } else {
            ElMessage.error(response.data.message || '删除失败')
        }
    } catch (error) {
        if (error !== 'cancel') {
            console.error('删除失败:', error)
            ElMessage.error('删除失败')
        }
    }
}

// 批量删除物料群组
const handleBatchDelete = async () => {
    if (selectedRows.value.length === 0) {
        ElMessage.warning('请选择要删除的项目')
        return
    }

    try {
        // 确认批量删除操作
        await ElMessageBox.confirm(`确定要删除选中的 ${selectedRows.value.length} 个项目吗？`, '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
        })

        // 批量删除：逐个调用删除API
        const deletePromises = selectedRows.value.map(row =>
            Maxios.post(`${API_BASE_URL}/Process/RoutingDelete`, { data: { row, Id: row.id } })
        )

        await Promise.all(deletePromises)
        ElMessage.success('批量删除成功')
        getItemGroups() // 刷新数据
    } catch (error) {
        if (error !== 'cancel') {
            console.error('批量删除失败:', error)
            ElMessage.error('批量删除失败')
        }
    }
}

// 导出物料群组数据（功能待开发）
const handleExport = () => {
    ElMessage.info('导出功能开发中...')
}

// 提交表单（新增或编辑物料群组）
const submitForm = async () => {
    if (!formRef.value) return

    try {
        // 表单验证
        await formRef.value.validate()

        // 准备请求数据
        const requestData = isEdit.value ? { ...form } : { ...form, AddProp: localStorage.getItem('userNickname') || '' }
        console.log(isEdit.value);

        // 根据操作类型调用不同的API
        if (isEdit.value) {
            // 编辑操作：调用更新API
            const response = await Maxios.put(`${API_BASE_URL}/Process/RoutingUpdate`, requestData)
            if (response.data.code === 200) {
                ElMessage.success(response.data.message)
            } else {
                ElMessage.error(response.data.message)
                return
            }
        } else {
            // 新增操作：调用添加API
            requestData.routStatus = "0"
            const response = await Maxios.post(`${API_BASE_URL}/Process/RoutingCreate`, requestData)
            if (response.data.code === 200) {
                ElMessage.success('添加成功')
            } else {
                ElMessage.error(response.data.message)
                return
            }
        }

        dialogVisible.value = false
        getItemGroups() // 刷新数据列表
    } catch (error) {
        console.error('提交失败:', error)
        ElMessage.error('操作失败')
    }
}

//事已至此写个简单的修改罢
const updStatus = async (row: any, state: number) => {
    row.routStatus = state
    const response = await Maxios.put(`${API_BASE_URL}/Process/RoutingUpdate`, row/*{AddProp:row.addProp,Reporting:row.reporting,ProcessMsg:row.processMsg,StepTypeId:row.stepTypeId,ProcessCode:row.processCode,ProcessName:row.processName}*/)
    if (response.data.code === 200) {
        ElMessage.success(response.data.message)
    } else {
        ElMessage.error(response.data.message)
        return
    }
    getItemGroups() // 刷新数据列表
}

// 重置表单数据到初始状态
const resetForm = () => {
    if (formRef.value) {
        formRef.value.resetFields() // 重置表单验证状态
    }
    // 重置表单数据为默认值
    Object.assign(form, {
        Id: 0,
        routingName: '', // 工艺路线名称
        routingImg: '', // 工艺路线图
        routingImgJSON: '', // 工艺路线流程
        routingTypeId: "", // 工艺路线类型
        routStatus: "", // 工艺路线状态
        routingMsg: "",//工艺路线描述
        AddProp: ''
    })
}

// 处理表格行选择变化
const handleSelectionChange = (selection: ItemGroup[]) => {
    selectedRows.value = selection // 更新选中的行数据
}

// 处理分页大小变化
const handleSizeChange = (size: number) => {
    console.log('分页大小变化:', { oldSize: pageSize.value, newSize: size })
    pageSize.value = size // 更新每页显示数量
    currentPage.value = 1 // 重置到第一页
    getItemGroups() // 重新获取数据（后端会处理分页）
}

// 处理当前页码变化
const handleCurrentChange = (page: number) => {
    console.log('页码变化:', { oldPage: currentPage.value, newPage: page })
    currentPage.value = page // 更新当前页码
    getItemGroups() // 重新获取数据（后端会处理分页）
}

// 执行搜索操作
const handleSearch = () => {
    currentPage.value = 1 // 重置到第一页

    // 保存搜索历史记录
    if (hasSearchConditions.value) {
        const currentSearch = {
            // ItemCode: searchForm.ProcessCode,
            ItemName: searchForm.RoutingName,
            ItemTypeId: searchForm.RoutStatus
        }

        // 避免重复添加相同的搜索条件
        const exists = searchHistory.value.some(item =>
            // item.ItemCode === currentSearch.ItemCode &&
            item.ItemName === currentSearch.ItemName &&
            item.ItemTypeId === currentSearch.ItemTypeId
        )

        if (!exists) {
            searchHistory.value.unshift(currentSearch) // 添加到历史记录开头
            // 只保留最近10条搜索历史
            if (searchHistory.value.length > 10) {
                searchHistory.value = searchHistory.value.slice(0, 10)
            }
        }
    }

    getItemGroups() // 执行搜索并获取数据（后端会处理分页和过滤）
}

// 切换搜索区域的显示/隐藏状态
const toggleSearchArea = () => {
    showSearchArea.value = !showSearchArea.value // 切换显示状态
}

// 刷新数据列表
const refreshData = () => {
    getItemGroups() // 重新获取数据
    ElMessage.success('数据已刷新')
}

// 切换浏览器全屏模式
const toggleFullscreen = () => {
    if (!document.fullscreenElement) {
        document.documentElement.requestFullscreen() // 进入全屏
    } else {
        document.exitFullscreen() // 退出全屏
    }
}
// 清空搜索条件
const clearSearch = () => {
    // searchForm.ProcessCode = '' // 清空编码搜索条件
    searchForm.RoutingName = '' // 清空名称搜索条件
    searchForm.RoutStatus = '' // 清空类型搜索条件
    handleSearch() // 执行搜索（此时会搜索所有数据）
    ElMessage.success('搜索条件已清空')
}

// ==================== 计算属性 ====================
// 计算属性：检查是否有搜索条件
const hasSearchConditions = computed(() => {
    return searchForm.RoutingName || searchForm.RoutStatus // 任一条件有值即为有搜索条件
})

// 获取当前搜索条件的文本描述
const getSearchConditionsText = () => {
    const conditions = []
    // if (searchForm.ProcessCode) conditions.push(`编码: ${searchForm.ProcessCode}`)
    if (searchForm.RoutingName) conditions.push(`名称: ${searchForm.RoutingName}`)
    if (searchForm.RoutStatus) {
        // const groupType = groupTypes.value.find(type => type.id === searchForm.RoutingTypeId)
        conditions.push(`类型: ${searchForm.RoutStatus}`)
    }
    return conditions.join(', ') // 用逗号连接所有条件
}

// 获取搜索历史项的文本描述
const getSearchHistoryText = (item: { ItemName: string, ItemTypeId: string }) => {
    const conditions = []
    // if (item.ItemCode) conditions.push(`编码: ${item.ItemCode}`)
    if (item.ItemName) conditions.push(`名称: ${item.ItemName}`)
    if (item.ItemTypeId) {
        // const groupType = groupTypes.value.find(type => type.id === item.ItemTypeId)
        conditions.push(`类型: ${item.ItemTypeId}`)
    }
    return conditions.join(', ') || '空搜索' // 如果没有条件则显示"空搜索"
}

// 加载搜索历史记录到搜索表单
const loadSearchHistory = (item: { ItemCode: string, ItemName: string, ItemTypeId: string }) => {
    // searchForm.ProcessCode = item.ItemCode // 填充编码搜索条件
    searchForm.RoutingName = item.ItemName // 填充名称搜索条件
    searchForm.RoutStatus = item.ItemTypeId // 填充类型搜索条件
    handleSearch() // 执行搜索
    ElMessage.success('已加载搜索历史')
}

// 处理键盘快捷键事件
const handleKeydown = (event: KeyboardEvent) => {
    // Ctrl + F 切换搜索区域显示/隐藏
    if (event.ctrlKey && event.key === 'f') {
        event.preventDefault() // 阻止默认行为
        toggleSearchArea()
    }
    // F5 刷新数据
    if (event.key === 'F5') {
        event.preventDefault() // 阻止默认行为
        refreshData()
    }
}


//#endregion
</script>

<style scoped>
.el-dropdown-link {
    cursor: pointer;
    color: var(--el-color-primary);
    display: flex;
    align-items: center;
    margin: 0 5px;
    margin-top: 8px;
}

.item-group-container {
    padding: 20px;
    background-color: #f5f5f5;
    min-height: 100vh;
}

.top-section {
    background: white;
    padding: 20px;
    border-radius: 8px;
    margin-bottom: 20px;
    display: flex;
    align-items: center;
    gap: 20px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.search-area {
    flex: 1;
    display: flex;
    gap: 10px;
    align-items: center;
    flex-wrap: wrap;
}

.search-status {
    width: 100%;
    margin-bottom: 10px;
}

.search-input {
    width: 200px;
}

.search-btn {
    display: flex;
    align-items: center;
    gap: 5px;
}

.clear-btn {
    display: flex;
    align-items: center;
    gap: 5px;
}

.history-btn {
    display: flex;
    align-items: center;
    gap: 5px;
}

.action-buttons {
    display: flex;
    gap: 10px;
}

.action-btn {
    display: flex;
    align-items: center;
    gap: 5px;
}

.delete-btn {
    background-color: #f56c6c;
    border-color: #f56c6c;
}

.delete-btn:hover {
    background-color: #f78989;
    border-color: #f78989;
}

.utility-icons {
    display: flex;
    gap: 15px;
}

.icon-btn {
    font-size: 18px;
    color: #606266;
    cursor: pointer;
    padding: 5px;
    border-radius: 4px;
    transition: all 0.3s;
}

.icon-btn:hover {
    color: #409eff;
    background-color: #f0f9ff;
}

.icon-btn.active {
    color: #409eff;
    background-color: #f0f9ff;
}

.table-section {
    background: white;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.data-table {
    width: 100%;
}

.search-icon {
    margin-left: 5px;
    font-size: 12px;
    color: #909399;
}

.sort-icon {
    margin-left: 3px;
    font-size: 12px;
    color: #909399;
}

.action-link {
    color: #409eff;
    text-decoration: none;
    margin: 0 5px;
}

.delete-link {
    color: #f56c6c;
}

.pagination-section {
    background: white;
    padding: 20px;
    border-radius: 8px;
    margin-top: 20px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.data-summary {
    color: #606266;
    font-size: 14px;
}

.pagination-controls {
    display: flex;
    align-items: center;
}

.pagination-controls .el-pagination {
    margin: 0;
}

.dialog-footer {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
}

/* 搜索区域动画 */
.search-slide-enter-active,
.search-slide-leave-active {
    transition: all 0.3s ease;
}

.search-slide-enter-from,
.search-slide-leave-to {
    opacity: 0;
    transform: translateY(-10px);
    max-height: 0;
}

.search-slide-enter-to,
.search-slide-leave-from {
    opacity: 1;
    transform: translateY(0);
    max-height: 100px;
}

/* 响应式设计 */
@media (max-width: 768px) {
    .top-section {
        flex-direction: column;
        align-items: stretch;
    }

    .search-input {
        width: 100%;
    }

    .action-buttons {
        justify-content: center;
    }

    .utility-icons {
        justify-content: center;
    }

    .pagination-section {
        flex-direction: column;
        gap: 15px;
    }
}

/* ----------------------------------------------------- */
.flow-container {
    position: relative;
    height: 800px;
}

.top-container {
    position: absolute;
    top: 0;
    width: 100%;
    display: flex;
    justify-content: space-between;
    padding: 10px;
    /* border-bottom: 1px solid #7300ff; */
}

.left-panel {
    position: absolute;
    left: 0;
    top: 120px;
    width: 200px;
    padding: 10px;
    background: rgba(245, 247, 250, 0.9);
    border-right: 1px solid #e4e7ed;
}

.right-panel {
    position: absolute;
    right: 0;
    top: 60px;
    width: 200px;
    padding: 10px;
    background: rgba(245, 247, 250, 0.9);
    border-left: 1px solid #e4e7ed;
}

.drag-item {
    padding: 8px;
    margin: 5px 0;
    border-radius: 4px;
    text-align: center;
    cursor: move;
}

.start-node {
    background-color: rgba(103, 194, 58, 0.8);
    color: white;
}

.end-node {
    background-color: rgba(245, 108, 108, 0.8);
    color: white;
}

.custom-node {
    background-color: rgba(64, 158, 255, 0.8);
    color: white;
}

.panel-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 15px;
}

.panel-content {
    display: grid;
    gap: 10px;
}

.controls {
    position: relative;
    top: -4px;
    left: -10px;
}
</style>